package com.corpgovernment.organization.mq;

import com.corpgovernment.common.apollo.OrganizationApollo;
import com.corpgovernment.common.common.CorpBusinessException;
import com.corpgovernment.common.mq.consumer.AbstractMultiTenantRocketMQConsumer;
import com.corpgovernment.common.mq.enums.MessageBizTypeEnum;
import com.corpgovernment.common.utils.HttpHuToolUtils;
import com.corpgovernment.common.utils.LogSplicingUtils;
import com.corpgovernment.organization.Bo.CommonSupplierUrlBo;
import com.corpgovernment.organization.Bo.GetOpenCardInfoMQBo;
import com.corpgovernment.organization.constant.OrganizationResponseCodeEnum;
import com.corpgovernment.organization.dataloader.BasicDataClientLoader;
import com.corpgovernment.organization.dataloader.db.MbSupplierCompanyLoader;
import com.corpgovernment.organization.dataloader.db.MbUserOrgRelationLoader;
import com.corpgovernment.organization.dto.GetCardReq;
import com.corpgovernment.organization.dto.GetCardRsp;
import com.corpgovernment.organization.entity.db.MbOrgEmployeeInfo;
import com.corpgovernment.organization.entity.db.MbOrgEmployeeOpenCardLog;
import com.corpgovernment.organization.entity.db.MbOrgEmployeeOpenCardRecord;
import com.corpgovernment.organization.mapper.MbOpenCardMainTableMapper;
import com.corpgovernment.organization.model.MbUserOrgRelationModel;
import com.corpgovernment.organization.model.SupplierCompanyModel;
import com.corpgovernment.organization.service.CtripOpenCardService;
import com.corpgovernment.organization.service.IOrganizationEmployeeService;
import com.corpgovernment.organization.service.IOrganizationInfoService;
import com.corpgovernment.organization.service.MbOrgEmployeeOpenCardLogService;
import com.corpgovernment.organization.service.MbOrgEmployeeOpenCardRecordService;
import com.ctrip.corp.obt.generic.core.context.TenantContext;
import com.ctrip.corp.obt.generic.utils.CollectionUtils;
import com.ctrip.corp.obt.generic.utils.JsonUtils;
import com.ctrip.corp.obt.generic.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyContext;
import org.apache.rocketmq.common.message.MessageExt;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.nio.charset.StandardCharsets;
import java.util.Date;
import java.util.List;
import java.util.Objects;

@Component
@Slf4j
public class GetOpenCardInfoMQConsumer extends AbstractMultiTenantRocketMQConsumer {

    @Autowired
    private BasicDataClientLoader basicDataClientLoader;
    @Autowired
    private MbOrgEmployeeOpenCardRecordService orgEmployeeOpenCardRecordService;
    @Autowired
    private OrganizationApollo organizationApollo;
    @Autowired
    private MbUserOrgRelationLoader userOrgRelationLoader;
    @Autowired
    private MbSupplierCompanyLoader mbSupplierCompanyLoader;
    @Autowired
    private IOrganizationInfoService organizationInfoService;
    @Autowired
    private CtripOpenCardService ctripOpenCardService;
    @Autowired
    private MbOpenCardMainTableMapper mbOpenCardMainTableMapper;
    @Autowired
    private MbOrgEmployeeOpenCardLogService mbOrgEmployeeOpenCardLogService;

    @Autowired
    private IOrganizationEmployeeService organizationEmployeeService;

    private final static String PREFIX_OBT = "obt";

    @Override
    protected void consume(MessageExt messageExt, ConsumeConcurrentlyContext context) {
        String msg = new String(messageExt.getBody(), StandardCharsets.UTF_8);
        if (StringUtils.isBlank(msg)){
            log.error("员工开发收到的消息为空");
            return;
        }
        GetOpenCardInfoMQBo getOpenCardInfoMQBo = JsonUtils.parse(msg, GetOpenCardInfoMQBo.class);
        process(getOpenCardInfoMQBo);
    }

    /**
     * 任务执行
     * @return
     */
    public boolean process(GetOpenCardInfoMQBo getOpenCardInfoMQBo){
        StringBuilder logContext = new StringBuilder();
        try {
            LogSplicingUtils.addLogContext(logContext, "开始获取开卡信息");
            LogSplicingUtils.addLogContext(logContext, "入参：%s", JsonUtils.toJsonString(getOpenCardInfoMQBo));

            MbUserOrgRelationModel mbUserOrgRelationModel = userOrgRelationLoader.getRelationByUid(getOpenCardInfoMQBo.getUid());
            if (mbUserOrgRelationModel == null){
                throw new CorpBusinessException(OrganizationResponseCodeEnum.COMPANY_ACCOUNT_UID_CONFIG_ERROR);
            }
            List<SupplierCompanyModel> companyConfigList = ctripOpenCardService.
                    getParentConfig(mbUserOrgRelationModel.getOrgId());
            if (CollectionUtils.isEmpty(companyConfigList)){
                log.error("orgId:{}的配置为空", mbUserOrgRelationModel.getOrgId());
                throw new CorpBusinessException(OrganizationResponseCodeEnum.COMPANY_ACCOUNT_CONFIG_EMPTY);
            }

            String corporateEntity = null;
            if(ctripOpenCardService.getCorporateEntitySyncFlag()){
                MbOrgEmployeeInfo orgEmployeeInfo = organizationEmployeeService.findAllByUid(getOpenCardInfoMQBo.getUid());
                if(Objects.nonNull(orgEmployeeInfo)) {
                    corporateEntity = orgEmployeeInfo.getCorporateEntity();
                }
            }

            SupplierCompanyModel companyConfig = companyConfigList.get(0);

            //获取请求地址
            CommonSupplierUrlBo commonUrl = CommonSupplierUrlBo.getCommonSupplierUrl(organizationApollo.getCtripUrl(),
                    companyConfig.getSupplierCorpId(),
                    companyConfig.getSubAccountCode(),
                    logContext);
            if (Objects.isNull(commonUrl)){
                return false;
            }

            GetCardRsp cardInfo = this.getCardInfo(commonUrl, getOpenCardInfoMQBo.getUid(), logContext);
            if (Objects.isNull(cardInfo) || BooleanUtils.isFalse(cardInfo.getIsOpened())){
                addFailLog(getOpenCardInfoMQBo.getUid(),null , cardInfo.getStatus().getErrorCode(), getOpenCardInfoMQBo.getBatchNo(),2);
                LogSplicingUtils.addLogContext(logContext,"开卡失败");
            }

            if (Objects.nonNull(cardInfo) && BooleanUtils.isTrue(cardInfo.getIsOpened())){
                MbOrgEmployeeOpenCardRecord existRecord = orgEmployeeOpenCardRecordService.selectByUid(getOpenCardInfoMQBo.getUid());
                MbOrgEmployeeOpenCardRecord orgEmployeeOpenCardRecord = new MbOrgEmployeeOpenCardRecord();
                orgEmployeeOpenCardRecord.setSupplierUid(cardInfo.getUid());
                orgEmployeeOpenCardRecord.setPlatUid(getOpenCardInfoMQBo.getUid());
                orgEmployeeOpenCardRecord.setName(cardInfo.getName());
                orgEmployeeOpenCardRecord.setOpenCardUid(this.getOpenCardUid(PREFIX_OBT, getOpenCardInfoMQBo.getUid()));
                orgEmployeeOpenCardRecord.setSubAccountId(cardInfo.getSubAccountID());
                orgEmployeeOpenCardRecord.setSubAccountName(cardInfo.getSubAccountName());
                orgEmployeeOpenCardRecord.setSetDefaultSendConfig(true);
                orgEmployeeOpenCardRecord.setDatachangeCreatetime(new Date());
                orgEmployeeOpenCardRecord.setCorporateEntity(corporateEntity);
                if (existRecord == null){
                    orgEmployeeOpenCardRecord.setDatachangeLasttime(new Date());
                    orgEmployeeOpenCardRecordService.insert(orgEmployeeOpenCardRecord);
                    return true;
                }
                synchronized (this){
                    mbOpenCardMainTableMapper.addSuccessNum(getOpenCardInfoMQBo.getBatchNo());
                }
                orgEmployeeOpenCardRecord.setId(existRecord.getId());
                orgEmployeeOpenCardRecordService.update(orgEmployeeOpenCardRecord);
            }
            return true;
        }catch (Exception e){
            log.error("获取开卡信息：{}", e);
        }finally {
            log.info("{}", logContext);
        }
        return false;
    }
    public void addFailLog(String uid, String failReason,String failedCode, Long batchNo,Integer failedType){
        MbOrgEmployeeOpenCardLog openCardLog = new MbOrgEmployeeOpenCardLog();
        openCardLog.setPlatUid(uid);
        openCardLog.setFailReason(failReason);
        openCardLog.setDatachangeCreatetime(new Date());
        openCardLog.setDatachangeLasttime(new Date());
        openCardLog.setBatchNo(batchNo);
        openCardLog.setFailedType(failedType);
        openCardLog.setFailedCode(failedCode);
        mbOrgEmployeeOpenCardLogService.insert(openCardLog);
    }

    /**
     * 获取供应商开卡信息
     * @param commonSupplierUrlBo
     * @param uid
     * @param logContext
     * @return
     */
    public GetCardRsp getCardInfo(CommonSupplierUrlBo commonSupplierUrlBo, String uid, StringBuilder logContext){
        try {
            CommonSupplierUrlBo.UrlInfo getOpenCardInfo = commonSupplierUrlBo.getGetOpenCardInfo();
            String ticket = basicDataClientLoader.ctripTokenByCorpID(getOpenCardInfo.getCorpId(), getOpenCardInfo.getSupplierCode());
            GetCardReq getCardReq = new GetCardReq();
            getCardReq.setTicket(ticket);
            getCardReq.setCorpID(getOpenCardInfo.getCorpId());
            getCardReq.setEmployeeID(this.getOpenCardUid(PREFIX_OBT, uid));
            LogSplicingUtils.addLogContext(logContext, "获取开卡信息 req：%s", JsonUtils.toJsonString(getCardReq));
            String result = HttpHuToolUtils.httpHuToolPost("获取开卡信息", getOpenCardInfo.getUrl(), JsonUtils.toJsonString(getCardReq));
            LogSplicingUtils.addLogContext(logContext, "获取开卡信息 req：%s", result);
            return JsonUtils.parse(result, GetCardRsp.class);
        }catch (Exception e){
            log.error("{}", e);
        }
        return null;
    }

    /**
     * 获取拼接卡号
     * @param prefix
     * @param uid
     * @return
     */
    public String getOpenCardUid(String prefix, String uid){
        return String.format("%s_%s_%s", prefix, TenantContext.getTenantId(), uid);
    }

    @Override
    protected MessageBizTypeEnum getMessageBizType() {
        return MessageBizTypeEnum.GET_OPEN_CARD_INFO;
    }
}
